<script lang="tsx" setup>
import { computed, onMounted, onUnmounted, ref, watch } from 'vue';
import { localStg } from '@/utils/storage';
import { $t } from '@/locales';

defineOptions({ name: 'UpdateLatest' });

/** 版本信息接口 */
interface VersionInfo {
    applicationName: string;
    version: string;
    downloadUrl: string;
    desc: string;
    isLatest: boolean;
    createTime: string;
}

/** 下载进度信息 */
interface DownloadProgress {
    progress: number;
    downloadedSize: number;
    totalSize: number;
    speed: number;
}

/** 组件状态 */
const versionUrl = ref('http://dc.yeziji.xyz/api/v1/application/get/latest?type=1');
const currentVersion = ref<VersionInfo | null>(null);
const latestVersion = ref<VersionInfo | null>(null);
const fetchLoading = ref(false);
const downloadLoading = ref(false);
const downloadProgress = ref<DownloadProgress>({
    progress: 0,
    downloadedSize: 0,
    totalSize: 0,
    speed: 0
});

/** 是否有新版本可用 */
const hasNewVersion = computed(() => {
    if (!currentVersion.value || !latestVersion.value) return false;
    return currentVersion.value.version !== latestVersion.value.version;
});

/** 格式化文件大小 */
function formatFileSize(bytes: number): string {
    if (bytes === 0) return '0 B';
    const k = 1024;
    const sizes = ['B', 'KB', 'MB', 'GB'];
    const i = Math.floor(Math.log(bytes) / Math.log(k));
    return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
}

/** 格式化下载速度 */
function formatSpeed(bytesPerSecond: number): string {
    return formatFileSize(bytesPerSecond) + '/s';
}

/** 获取版本信息 */
async function fetchVersionInfo() {
    if (!versionUrl.value.trim()) {
        window.$message?.error($t('page.home.updateLatest.fetchFailed'));
        return;
    }

    fetchLoading.value = true;
    try {
        const result = await window.electronAPI?.fetchVersionInfo(versionUrl.value);
        console.log('res: ', result);
        if (result?.success && result.data) {
            latestVersion.value = result.data;

            // 保存到缓存
            await window.electronAPI?.saveVersionCache(result.data);

            // 检查是否有新版本
            if (hasNewVersion.value) {
                window.$message?.info($t('page.home.updateLatest.newVersionAvailable'));
            } else {
                window.$message?.success($t('page.home.updateLatest.alreadyLatest'));
            }
        } else {
            window.$message?.error(result?.message || $t('page.home.updateLatest.fetchFailed'));
        }
    } catch (error: any) {
        window.$message?.error($t('page.home.updateLatest.fetchFailed') + ': ' + error.message);
    } finally {
        fetchLoading.value = false;
    }
}

/** 获取 JDK 路径 */
function getJdkPath(): string | null {
    return localStg.get('jdkPath');
}

/** 获取 JAR 路径 */
function getJarPath(): string | null {
    return localStg.get('jarPath');
}

/** 检查服务是否正在运行 */
async function checkServiceRunning(): Promise<boolean> {
    try {
        const result = await window.electronAPI?.checkServiceHealth();
        return result?.success || false;
    } catch {
        return false;
    }
}

/** 下载文件 */
// eslint-disable-next-line complexity
async function downloadFile() {
    if (!latestVersion.value) {
        window.$message?.error($t('page.home.updateLatest.fetchFailed'));
        return;
    }

    // 检查服务是否正在运行
    const isServiceRunning = await checkServiceRunning();
    if (isServiceRunning) {
        window.$message?.warning($t('page.home.updateLatest.serviceRunningWarning'));
        return;
    }

    // 获取下载路径 - 改为使用 jarPath
    let downloadPath = getJarPath();
    if (!downloadPath) {
        const pathResult = await window.electronAPI?.selectDownloadPath();
        if (!pathResult?.success || !pathResult.path) {
            window.$message?.error($t('page.home.updateLatest.downloadPathRequired'));
            return;
        }
        downloadPath = pathResult.path;
    } else {
        // 如果有 jarPath，需要提取目录路径
        const lastSlashIndex = Math.max(
            downloadPath.lastIndexOf('\\'),
            downloadPath.lastIndexOf('/')
        );
        if (lastSlashIndex !== -1) {
            downloadPath = downloadPath.substring(0, lastSlashIndex);
        }
    }

    const fileName = latestVersion.value.applicationName;
    const fullPath = `${downloadPath}\\${fileName}`;

    // 检查文件是否已存在
    const fileExistsResult = await window.electronAPI?.checkFileExists(fullPath);
    if (fileExistsResult?.exists) {
        const confirmed = await new Promise<boolean>((resolve) => {
            window.$dialog?.warning({
                title: $t('page.home.updateLatest.confirmOverwrite'),
                content: `${fileName} ${$t('page.home.updateLatest.confirmOverwrite')}`,
                positiveText: $t('page.home.updateLatest.overwrite'),
                negativeText: $t('page.home.updateLatest.cancel'),
                onPositiveClick: () => resolve(true),
                onNegativeClick: () => resolve(false)
            });
        });

        if (!confirmed) return;
    }

    downloadLoading.value = true;
    downloadProgress.value = {
        progress: 0,
        downloadedSize: 0,
        totalSize: 0,
        speed: 0
    };

    try {
        // 监听下载进度
        window.electronAPI?.onDownloadProgress((progress: DownloadProgress) => {
            downloadProgress.value = progress;
        });

        const result = await window.electronAPI?.downloadFile({
            downloadUrl: latestVersion.value.downloadUrl,
            savePath: downloadPath,
            fileName: fileName
        });

        if (result?.success) {
            window.$message?.success($t('page.home.updateLatest.downloadComplete'));

            // 更新 jarPath 为新下载的文件路径
            const newJarPath = `${downloadPath}\\${fileName}`;
            localStg.set('jarPath', newJarPath);

            // 更新当前版本为最新版本
            currentVersion.value = { ...latestVersion.value };

            // 创建一个纯净的版本对象副本，避免传递不可序列化的属性
            const versionToSave: VersionInfo = {
                applicationName: latestVersion.value.applicationName,
                version: latestVersion.value.version,
                downloadUrl: latestVersion.value.downloadUrl,
                desc: latestVersion.value.desc,
                isLatest: latestVersion.value.isLatest,
                createTime: latestVersion.value.createTime
            };
            await window.electronAPI?.saveVersionCache(versionToSave);
        } else {
            window.$message?.error(result?.message || $t('page.home.updateLatest.downloadFailed'));
        }
    } catch (error: any) {
        console.error(error);
        window.$message?.error($t('page.home.updateLatest.downloadFailed') + ': ' + error.message);
    } finally {
        downloadLoading.value = false;
        window.electronAPI?.offDownloadProgress();
        downloadProgress.value = {
            progress: 0,
            downloadedSize: 0,
            totalSize: 0,
            speed: 0
        };
    }
}

/** 取消下载 */
async function cancelDownload() {
    try {
        await window.electronAPI?.cancelDownload();
        downloadLoading.value = false;
        window.$message?.info($t('page.home.updateLatest.downloadCanceled'));
    } catch (error: any) {
        window.$message?.error($t('page.home.updateLatest.cancelDownloadFailed') + ': ' + error.message);
    }
}

/** 加载缓存的版本信息 */
async function loadCachedVersion() {
    try {
        const result = await window.electronAPI?.getCachedVersion();
        if (result?.success && result.data) {
            currentVersion.value = result.data;
        }
    } catch (error) {
        console.warn($t('page.home.updateLatest.loadCachedVersionFailed') + ':', error);
    }
}

/** 组件挂载时加载缓存版本 */
onMounted(() => {
    loadCachedVersion();
});

/** 组件卸载时清理下载进度监听 */
onUnmounted(() => {
    window.electronAPI?.offDownloadProgress();
});
</script>

<template>
    <div class="flex-col-stretch gap-16px overflow-hidden lt-sm:overflow-auto">
        <NCard
            :title="$t('page.home.updateLatest.title')"
            :bordered="false"
            size="small"
            class="sm:flex-1-hidden card-wrapper"
        >
            <div class="flex-col-stretch gap-12px">
                <!-- 版本 URL 输入 -->
                <div class="flex-y-center gap-8px">
                    <span class="flex-shrink-0 w-120px"
                        >{{ $t('page.home.updateLatest.versionUrl') }}:</span
                    >
                    <NInput
                        v-model:value="versionUrl"
                        :placeholder="$t('page.home.updateLatest.versionUrl')"
                        class="flex-1"
                    />
                    <NButton type="primary" :loading="fetchLoading" @click="fetchVersionInfo">
                        {{ $t('page.home.updateLatest.fetch') }}
                    </NButton>
                </div>

                <!-- 版本信息显示 -->
                <div class="flex-col-stretch gap-8px">
                    <!-- 当前版本 -->
                    <div class="flex-y-center gap-8px">
                        <span class="flex-shrink-0 w-120px"
                            >{{ $t('page.home.updateLatest.currentVersion') }}:</span
                        >
                        <NTag type="info">{{ currentVersion?.version || '-' }}</NTag>
                    </div>

                    <!-- 最新版本 -->
                    <div class="flex-y-center gap-8px">
                        <span class="flex-shrink-0 w-120px"
                            >{{ $t('page.home.updateLatest.latestVersion') }}:</span
                        >
                        <NTag
                            :type="
                                latestVersion ? (hasNewVersion ? 'warning' : 'success') : 'default'
                            "
                            >{{ latestVersion?.version || '-' }}</NTag
                        >
                        <NTag v-if="hasNewVersion" type="error" size="small">{{
                            $t('page.home.updateLatest.newVersionAvailable')
                        }}</NTag>
                    </div>

                    <!-- 应用名称 -->
                    <div v-if="latestVersion" class="flex-y-center gap-8px">
                        <span class="flex-shrink-0 w-120px"
                            >{{ $t('page.home.updateLatest.applicationName') }}:</span
                        >
                        <span>{{ latestVersion.applicationName }}</span>
                    </div>

                    <!-- 更新描述 -->
                    <div v-if="latestVersion" class="flex-y-center gap-8px">
                        <span class="flex-shrink-0 w-120px"
                            >{{ $t('page.home.updateLatest.description') }}:</span
                        >
                        <span>{{ latestVersion.desc }}</span>
                    </div>

                    <!-- 发布时间 -->
                    <div v-if="latestVersion" class="flex-y-center gap-8px">
                        <span class="flex-shrink-0 w-120px"
                            >{{ $t('page.home.updateLatest.createTime') }}:</span
                        >
                        <span>{{ latestVersion.createTime }}</span>
                    </div>

                    <!-- 下载 URL -->
                    <div v-if="latestVersion" class="flex-y-center gap-8px">
                        <span class="flex-shrink-0 w-120px"
                            >{{ $t('page.home.updateLatest.downloadUrl') }}:</span
                        >
                        <span class="text-xs text-gray-500 truncate flex-1">{{
                            latestVersion?.downloadUrl || '-'
                        }}</span>
                    </div>
                </div>

                <!-- 下载进度 -->
                <div v-if="downloadLoading" class="flex-col-stretch gap-8px">
                    <div class="flex-y-center gap-8px">
                        <span class="flex-shrink-0 w-120px"
                            >{{ $t('page.home.updateLatest.downloadProgress') }}:</span
                        >
                        <NProgress
                            type="line"
                            :percentage="downloadProgress.progress"
                            :show-indicator="true"
                            class="flex-1"
                        />
                    </div>
                    <div class="flex-y-center gap-8px">
                        <span class="flex-shrink-0 w-120px"
                            >{{ $t('page.home.updateLatest.downloadSpeed') }}:</span
                        >
                        <span>{{ formatSpeed(downloadProgress.speed) }}</span>
                        <span class="text-gray-500">
                            ({{ formatFileSize(downloadProgress.downloadedSize) }} /
                            {{ formatFileSize(downloadProgress.totalSize) }})
                        </span>
                    </div>
                </div>

                <!-- 操作按钮 -->
                <div class="flex-y-center gap-8px">
                    <NButton
                        v-if="latestVersion && !downloadLoading"
                        type="success"
                        @click="downloadFile"
                    >
                        {{ $t('page.home.updateLatest.download') }}
                    </NButton>
                    <NButton v-if="downloadLoading" type="error" @click="cancelDownload">
                        {{ $t('page.home.updateLatest.cancel') }}
                    </NButton>
                </div>
            </div>
        </NCard>
    </div>
</template>

<style scoped>
.card-wrapper {
    @apply flex-col-stretch gap-16px overflow-hidden;
}
</style>
